package org.springblade.modules.platform.websocket;


import com.alibaba.fastjson.JSONObject;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.platform.websocket.config.WebSokcetChannelGroup;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@ChannelHandler.Sharable
@Slf4j
@Component
public class MyWebSocketHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
	private static final AttributeKey<String> CONNECTION_ID = AttributeKey.valueOf("connectionId");

	private  WebSocketPullService webSocketPullService;

	public MyWebSocketHandler(WebSocketPullService webSocketPullService){
		this.webSocketPullService = webSocketPullService;
	}
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame){
		if (frame instanceof TextWebSocketFrame) {
			String request = ((TextWebSocketFrame) frame).text();
			log.info("接受数据:{}",request+"=========="+ctx.attr(CONNECTION_ID).get());
			JSONObject jsonObject = JSONObject.parseObject(request);
			String collectData = jsonObject.get("webSocketCode").toString();
			if(collectData.equalsIgnoreCase("COLLECT_DATA")){
				webSocketPullService.setConnectionId(jsonObject,ctx.attr(CONNECTION_ID).get());
			}
			log.info("异步接受数据:{}",request+"=========="+ctx.attr(CONNECTION_ID).get());
			Map<String, List<String>> map = WebSokcetChannelGroup.MAP;
			if(!Func.isEmpty(map)){
				if(map.containsKey(collectData)){
					List<String> stringList = map.get(collectData);
					stringList.add(ctx.attr(CONNECTION_ID).get());
					map.put(collectData,stringList);
				}else {
					List<String> list = new ArrayList<>();
					list.add(ctx.attr(CONNECTION_ID).get());
					map.put(collectData,list);
				}
			}else {
				List<String> list = new ArrayList<>();
				list.add(ctx.attr(CONNECTION_ID).get());
				map.put(collectData,list);
			}
		}
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		String connectionId = UUID.randomUUID().toString();
		ctx.attr(CONNECTION_ID).set(connectionId);
		WebSokcetChannelGroup.channels.add(ctx.channel());
		super.channelActive(ctx);
		log.info("wbeSocket通道已经连接：{}",ctx.channel().remoteAddress() + ", connectionId=" + connectionId +",大小="+WebSokcetChannelGroup.channels.size());
	}
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		log.info("wbeSocket通道已经断开" +ctx.channel().remoteAddress() + ", connectionId=" + ctx.attr(CONNECTION_ID).get());
		Map<String, List<String>> map = WebSokcetChannelGroup.MAP;
		map.forEach((x,y)-> y.remove(ctx.attr(CONNECTION_ID).get()));
		super.channelInactive(ctx);
	}
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		Map<String, List<String>> map = WebSokcetChannelGroup.MAP;
		map.forEach((x,y)-> y.remove(ctx.attr(CONNECTION_ID).get()));
		log.info("wbeSocket异常" + ctx.channel().remoteAddress() + ", connectionId=" + ctx.attr(CONNECTION_ID).get());
		log.info("wbeSocket异常:{}",cause.toString());
		cause.printStackTrace();
		ctx.close();
	}

}
